/**
 @file sys_usw_l3if.h

 @date 2009-12-7

 @version v2.0

---file comments----
*/
#ifndef _SYS_USW_L3IF
#define _SYS_USW_L3IF
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************
*
* Header Files
*
***************************************************************/
#include "ctc_l3if.h"
#include "ctc_spool.h"
#include "ctc_vector.h"
#include "sys_usw_fpa.h"

/**********************************************************************************
                          Defines and Macros
***********************************************************************************/

#define SYS_L3IF_ROUTER_MAC_NUM_PER_ENTRY    8
#define SYS_L3IF_ROUTER_MAC_PREFIX_NUM       6
#define SYS_L3IF_MAX_ROUTER_MAC_ID           0x1ff
#define SYS_L3IF_ROUTER_MAC_NUM_PER_IF           8
#define SYS_L3IF_MAX_DS_PROF_SIZE 12
typedef uint32 dsprofile_t[SYS_L3IF_MAX_DS_PROF_SIZE];

#define SYS_L3IF_INIT_CHECK()                                  \
{                                                              \
    LCHIP_CHECK(lchip);                                        \
    if (p_usw_l3if_master[lchip] == NULL)                          \
    {                                                          \
        SYS_L3IF_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
        return CTC_E_NOT_INIT; \
    }                                                          \
}

struct sys_l3if_router_mac_s
{
    mac_addr_t  mac;
    uint32       postfix_bmp:6;/*MAX 6 bit*/
    uint32       prefix_idx:3; /*MAX 5*/
    uint32       rsv:23;
};
typedef struct sys_l3if_router_mac_s sys_l3if_router_mac_t;

struct sys_l3if_rtmac_profile_s
{
    sys_l3if_router_mac_t mac_info[SYS_L3IF_ROUTER_MAC_NUM_PER_ENTRY];
    uint16  mac_ref[SYS_L3IF_ROUTER_MAC_NUM_PER_ENTRY];
    uint32 lchip:8;
    uint32 valid_bitmap:8;
    uint32 match_mode:8; /*0:lookup container, 1: exactly, 2:lookup void mac position*/
    uint32 new_node:8;
    uint32 profile_id:16;
    uint32 rsv:16;
};
typedef struct sys_l3if_rtmac_profile_s sys_l3if_rtmac_profile_t;

struct sys_l3if_macinner_profile_s
{
    uint32 lchip:8;
    uint32 type:8;               /*maninner & egs routermac share the struct*/
    uint32 profile_id:16;
    uint32 calc_len[0];      /*spool don't store Mac address  */
    void*  ds;
};
typedef struct sys_l3if_macinner_profile_s sys_l3if_macinner_profile_t;

struct sys_l3if_prop_s
{
    uint32  rtmac_index:16;
    uint32  egs_rtmac_index:16;/* for egress route mac*/
    uint32  gport;
    uint32  vlan_id:16;
    uint32  cvlan_id:16;    /*Phy-if use as dsfwd_offset when interface is member of ecmp-if*/
    uint32  vlan_ptr:16; /**< Vlanptr */
    uint32  l3if_id:16; /**< l3if id */
    uint32   rtmac_bmp:8; /* TM:routerMacSelBitmap in DsRouterMac  After TMM :software valid rtmac bitmap perinterface*/
    uint32   l3if_type:3; /**< the type of l3interface , CTC_L3IF_TYPE_XXX */
    uint32   user_egs_rtmac:1;
    uint32   bind_en:1;  /* use for service interface, if enable, means service interface with gport and vlan */
    uint32   valid:1;
    uint32   rsv:18;
};
typedef struct sys_l3if_prop_s sys_l3if_prop_t;

struct sys_l3if_rmac_block_s
{
    ctc_fpa_block_t fpab;
};
typedef struct sys_l3if_rmac_block_s sys_l3if_rmac_block_t;

struct sys_l3if_rmac_entry_s {
    ctc_fpa_entry_t fpae;
};
typedef struct sys_l3if_rmac_entry_s  sys_l3if_rmac_entry_t;

struct sys_l3if_master_s
{
    sal_mutex_t* mutex;
    sys_l3if_prop_t*  l3if_prop;
    ctc_hash_t* l3if_prop_hash; /* for lookup by port/vlan ,unbinded service if not in here*/
    ctc_vector_t* ecmp_group_vec;
    ctc_spool_t*  acl_spool;
    ctc_spool_t*  macinner_spool;
    ctc_spool_t* rtmac_spool;
    ctc_hash_t*  rmac_pp_hash;/* for rtmac entry id mapping to pp bitmap */
    mac_addr_t mac_prefix[SYS_L3IF_ROUTER_MAC_PREFIX_NUM];
    uint32 max_vrfid_num:16;
    uint32  opf_type_l3if_profile:8;
    uint32  opf_type_mac_profile:8;

    uint32  opf_type_macinner_profile:8;
    uint32  ofb_type_rtmac:8;   /* TMM: routermac tcam, range:0~510, 511 is reserved for system routermac. */
    uint32  default_entry_mode:1;
    uint32  rtmac_mode:1;     /* TMM: 1: using router mac entry mode. 0: using interface router mac mode. */
    uint32  egs_rtmac_mode:1; /* If set ,not config interface egress rtmac when value equal to system rtmac */
    uint32  keep_ivlan_en:1;
    uint32  rsv_start:12;

    uint32  rsv_end:12;
    uint32  rsv0:20;
};
typedef struct sys_l3if_master_s sys_l3if_master_t;

extern sys_l3if_master_t* p_usw_l3if_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

struct sys_l3if_ecmp_if_s
{
    uint32 hw_group_id:16;
    uint32 ecmp_member_base:16;
    uint32 failover_en:1;
    uint32 ecmp_group_type:3;     /* refer to ctc_nh_ecmp_type_t */
    uint32 intf_count:8;
    uint32 rsv:20;
    uint16 intf_array[SYS_USW_MAX_DEFAULT_ECMP_NUM];
};
typedef struct sys_l3if_ecmp_if_s sys_l3if_ecmp_if_t;




#define SYS_L3IF_DBG_OUT(level, FMT, ...)\
    CTC_DEBUG_OUT(l3if, l3if, L3IF_SYS, level, FMT, ##__VA_ARGS__)
/**********************************************************************************
                      Define API function interfaces
***********************************************************************************/

/**********************************************************************************
                    ----  L3 interfaces's  properties  ----
***********************************************************************************/
/**
 @brief    init l3 interface module
*/
extern int32
sys_usw_l3if_init(uint8 lchip, ctc_l3if_global_cfg_t* l3if_global_cfg);

/**
 @brief    deinit l3 interface module
*/
extern int32
sys_usw_l3if_deinit(uint8 lchip);

/**
@brief    Create  l3 interfaces
*/
extern int32
sys_usw_l3if_create(uint8 lchip, uint16 l3if_id, ctc_l3if_t* l3_if);

/**
   @brief    Delete  l3 interfaces
*/
extern int32
sys_usw_l3if_delete(uint8 lchip, uint16 l3if_id, ctc_l3if_t* l3_if);


extern int32
sys_usw_l3if_get_l3if_id(uint8 lchip, ctc_l3if_t* p_l3_if, uint16* l3if_id);

/**
@brief   Judge Routed port  according to global logic port ID
*/
extern bool
sys_usw_l3if_is_port_phy_if(uint8 lchip, uint32 gport);

/**
@brief   get port is subif port
*/
extern bool
sys_usw_l3if_is_port_sub_if(uint8 lchip, uint32 gport, uint8* double_vlan);

/**
   @brief    Config  l3 interface's  properties
*/
extern int32
sys_usw_l3if_set_property(uint8 lchip, uint16 l3if_id, ctc_l3if_property_t l3if_prop, uint32 value);

/**
@brief    Get  l3 interface's properties according to interface id
*/
extern int32
sys_usw_l3if_get_property(uint8 lchip, uint16 l3if_id, ctc_l3if_property_t l3if_prop, uint32* value);

/**
@brief    Set  l3 interface's acl properties according to interface id
*/
extern int32
sys_usw_l3if_set_acl_property(uint8 lchip, uint16 l3if_id, ctc_acl_property_t* acl_prop);

/**
@brief    Get  l3 interface's acl properties according to interface id
*/
extern int32
sys_usw_l3if_get_acl_property(uint8 lchip, uint16 l3if_id, ctc_acl_property_t* acl_prop);

/**
@brief    Set  l3 interface's acl properties according to acl league
*/
extern int32
sys_usw_l3if_set_acl_league_property(uint8 lchip, uint8 acl_pri, uint8 enable, uint8 sub_blk_cnt, uint8 * sub_blk_list);

/**
@brief    Set  l3 interface's properties according to interface id
*/
extern int32
sys_usw_l3if_set_exception3_en(uint8 lchip, uint16 l3if_id, uint8 index, bool enbale);

/**
@brief   Get  l3 interface's properties according to interface id
*/
extern int32
sys_usw_l3if_get_exception3_en(uint8 lchip, uint16 l3if_id, uint8 index, bool* enbale);

/**
@brief   Get  l3 interface's info,such as l3if id,vlanPtr etc
*/
extern int32
sys_usw_l3if_get_l3if_info(uint8 lchip, uint8 type, sys_l3if_prop_t* l3if_prop);

/**
@brief   Get  l3 interface's info,such as l3if id,vlanPtr etc
*/
extern int32
sys_usw_l3if_get_l3if_info_with_port_and_vlan(uint8 lchip, uint32 gport, uint16 vlan_id, uint16 cvlan_id, sys_l3if_prop_t* l3if_prop);

/**********************************************************************************
                   ----  L3 interfaces's router mac    ----
***********************************************************************************/
/**
@brief    Config  router mac
*/
extern int32
sys_usw_l3if_set_router_mac(uint8 lchip, mac_addr_t mac_addr);

/**
@brief    Get  router mac
*/
extern int32
sys_usw_l3if_get_router_mac(uint8 lchip, mac_addr_t mac_addr);

/**
     @brief      Config l3 interface router mac
*/
extern int32
sys_usw_l3if_set_interface_router_mac(uint8 lchip, uint16 l3if_id, ctc_l3if_router_mac_t router_mac);

/**
     @brief       Get l3 interface router mac
*/
extern int32
sys_usw_l3if_get_interface_router_mac(uint8 lchip, uint16 l3if_id, ctc_l3if_router_mac_t* router_mac);

extern int32
sys_usw_l3if_set_vmac_prefix(uint8 lchip,  uint32 prefix_idx, mac_addr_t mac_40bit);

extern int32
sys_usw_l3if_get_vmac_prefix(uint8 lchip,  uint32 prefix_idx, mac_addr_t mac_40bit);

extern int32
sys_usw_l3if_get_default_entry_mode(uint8 lchip);

extern int32
sys_usw_l3if_set_vrf_stats_en(uint8 lchip, ctc_l3if_vrf_stats_t* p_vrf_stats);

extern int32
sys_usw_l3if_get_vrf_statsid(uint8 lchip, uint16 vrfid, uint32* p_statsid);

extern int32
sys_usw_l3if_create_ecmp_if(uint8 lchip, ctc_l3if_ecmp_if_t* p_ecmp_if);

extern int32
sys_usw_l3if_destory_ecmp_if(uint8 lchip, uint16 ecmp_if_id);

extern int32
sys_usw_l3if_add_ecmp_if_member(uint8 lchip, uint16 ecmp_if_id, uint16 l3if_id);

extern int32
sys_usw_l3if_remove_ecmp_if_member(uint8 lchip, uint16 ecmp_if_id, uint16 l3if_id);

extern int32
sys_usw_l3if_get_ecmp_if_info(uint8 lchip, uint16 ecmp_if_id, sys_l3if_ecmp_if_t* p_ecmp_if);

extern int32
sys_usw_l3if_binding_inner_router_mac(uint8 lchip, mac_addr_t* p_mac_addr, uint16* route_mac_index);

extern int32
sys_usw_l3if_unbinding_inner_router_mac(uint8 lchip, uint16 route_mac_index);

extern int32
sys_usw_l3if_get_inner_router_mac(uint8 lchip, uint16 route_mac_index, mac_addr_t* mac);

extern int32
sys_usw_l3if_set_lm_en(uint8 lchip, uint16 l3if_id, uint8 enable);

extern int32
sys_usw_l3if_set_section_lock_en(uint8 lchip, uint16 l3if_id, uint8 enable);

extern int32
sys_usw_l3if_add_router_mac_entry(uint8 lchip, uint32 entry_id, ctc_l3if_rmac_entry_t* rmac_entry);

extern int32
sys_usw_l3if_remove_router_mac_entry(uint8 lchip, uint32 entry_id);

extern int32
sys_usw_l3if_get_router_mac_entry(uint8 lchip, uint32 entry_id, ctc_l3if_rmac_entry_t* rmac_entry);

extern int32
sys_usw_l3if_free_node_data(void* node_data, void* user_data);

extern int32
sys_usw_l3if_set_ecmp_if_vlan(uint8 lchip, uint32 gport, uint16 vlan_id);
extern int32
sys_usw_l3if_create_subif(uint8 lchip, uint16 l3if_id, ctc_l3if_t* l3_if);
extern int32
sys_usw_l3if_delete_subif(uint8 lchip, uint16 l3if_id, ctc_l3if_t* l3_if);
extern int32
sys_usw_l3if_register_entry_hash_db(uint8 lchip, void* user_data);

extern int32
sys_usw_l3if_lookup_entry_hash(uint8 lchip, uint32 entry_id, uint16* pp_bmp);
extern int32
sys_usw_l3if_add_entry_hash(uint8 lchip, uint32 entry_id, uint16 pp_bmp);
extern int32
sys_usw_l3if_remove_entry_hash(uint8 lchip, uint32 entry_id);

#ifdef __cplusplus
}
#endif

#endif /*_SYS_USW_L3IF*/

